package com.hengpeng.itfin.tools;

import java.math.BigDecimal;

import com.hengpeng.itfinbase.persist.BorrowInfo.DurationType;

public class InvestUtils
{
	/**
	 * <pre>
	 * 精度转换(四舍六入5成双)
	 * </pre>
	 * @param monthMoney 单位：分
	 * @return
	 */
	public static long accuracy(double monthMoney)
	{
		BigDecimal dec = new BigDecimal(String.valueOf(monthMoney));
		return dec.setScale(0, BigDecimal.ROUND_HALF_EVEN).longValue();
	}

	/**
	 * <pre>
	 * 等额本息还款（每月月供额=〔贷款本金×月利率×(1＋月利率)＾还款月数〕÷〔(1＋月利率)＾还款月数-1〕）
	 * </pre>
	 * @param money 金额
	 * @param rate 利率(百分数)
	 * @param duration 时长，月数
	 */
	public static long equalInterest(Long money, Double rate, int duration)
	{
		double monthRate = rate / (12 * 100);// 月利率
		double rates = 1;// (1＋月利率)＾还款月数
		for (int i = 0; i < duration; i++)
		{
			rates = rates * (1 + monthRate);
		}
		double month = (money * monthRate * rates) / (rates - 1);
		return accuracy(month);// 每月还款额
	}

	/**
	 * <pre>
	 * 等额本金还款总额（还款总额=(还款月数+1)*贷款额*月利率/2+贷款额）
	 * </pre>
	 * @param money 金额
	 * @param rate 利率(百分数)
	 * @param duration 时长，月数
	 */
	public static long equalPrincipal(Long money, Double rate, int duration)
	{
		double monthRate = rate / (12 * 100);// 月利率
		double total = (duration + 1) * money * monthRate / 2 + money;
		return accuracy(total);
	}

	/**
	 * <pre>
	 * 一次性还本付息的利息与按月付息到期还本总利息计算方式相同
	 * </pre>
	 * @param money 金额
	 * @param rate 利率(百分数)
	 * @param duration 时长，月数
	 */
	public static long rtcapitalInterest(Long money, Double rate, int duration, DurationType type)
	{
		long rtMoney = 0;
		switch (type)
		{
			case MONTH:
				rtMoney = accuracy(money * rate * duration / (100 * 12));
				break;
//			case DAY:
//				rtMoney = accuracy(money * rate * duration / (100 * 365));
//				break;
		}
		return rtMoney;
	}

	/**
	 * <pre>
	 * 按月付息每个月的利息
	 * </pre>
	 * @param money 金额
	 * @param rate 利率(百分数)
	 * @param duration 时长，月数
	 */
	public static long rtcapitalMonthInterest(Long money, Double rate, DurationType type)
	{
		long rtMoney = 0;
		switch (type)
		{
			case MONTH:
				rtMoney = accuracy(money * rate / (100 * 12));
				break;
//			case DAY:
//				rtMoney = accuracy(money * rate / (100 * 365));
//				break;
		}
		return rtMoney;
	}

	/**
	 * <pre>
	 * 等额本息还款每月应还本金金额
	 * </pre>
	 * @param money 金额
	 * @param rate 利率(百分数)
	 * @param duration 时长，月数
	 */
	public static Long[] equalInterestMonthBase(Long money, Double rate, int duration)
	{
		double monthRate = rate / (12 * 100);// 月利率
		long monthMoney = equalInterest(money, rate, duration);// 每月还款额
		Long[] allMonths = new Long[duration + 1];// 每月剩余本金
		long base = money;
		for (int i = 0; i <= duration; i++)
		{
			allMonths[i] = base;
			base = accuracy(base * (1 + monthRate) - monthMoney);
		}
		Long[] months = new Long[duration];// 每月应还本金
		Long totalMoney = 0L;
		for (int i = 1; i <= months.length; i++)
		{
			months[i - 1] = -(allMonths[i] - allMonths[i - 1]);
			totalMoney = totalMoney + months[i - 1];
		}
		months[0] = months[0] + money - totalMoney;
		return months;
	}

	/**
	 * <pre>
	 * 等额本金,每月应还利息
	 * </pre>
	 * @param money 金额
	 * @param rate 利率(百分数)
	 * @param duration 时长，月数
	 */
	public static Long[] equalPrincipalMonthInterest(Long money, Double rate, int duration)
	{
		double monthRate = rate / (12 * 100);// 月利率
		long monthBase = accuracy(money / duration);// 每月应还本金
		long monthLoss = money;// 每月剩余本金
		Long[] interest = new Long[duration];
		for (int i = 0; i < duration; i++)
		{
			interest[i] = accuracy(monthLoss * monthRate);
			monthLoss = monthLoss - monthBase;
		}
		return interest;
	}

	public static void main(String[] args)
	{
		Long months = equalInterest(300000L, 5.12, 36);
		System.out.println(months);
		System.out.println(months * 36);
		Long month1 = equalInterest(300000L, 5.12 + 2.12, 36);
		System.out.println(month1);
		// Long[] mons = equalInterestMonthBase(100000L, 5.12, 36);
	}
}
